// 家庭成员位置变化
package members

import (
	"net/http"
	"io/ioutil"
	"adai.design/homeserver/log"
	"encoding/json"
	"time"
	"adai.design/homeserver/db"
)

type location struct {
	Membership string `json:"membership"`
	Session    string `json:"session"`
	Home       string `json:"home"`
	State      string `json:"state"`
}

func (*location) ServeHTTP(response http.ResponseWriter, request *http.Request) {
	buf, err := ioutil.ReadAll(request.Body)
	if err == nil {
		log.Debug("request: %s", string(buf))

		var l location
		err = json.Unmarshal(buf, &l);
		if err != nil {
			db.Invalid(&db.InvalidInfo{
				Addr: request.RemoteAddr,
				Time: time.Now(),
				Type: db.InvalidHttps,
			})
		}

		membership := db.GetMembershipById(l.Membership)
		if membership == nil {
			response.Write([]byte(`{state":"failed"}`))
			db.Invalid(&db.InvalidInfo{
				Addr: request.RemoteAddr,
				Time: time.Now(),
				Type: db.InvalidHttps,
			})
			return
		}

		check := false
		for _, c := range membership.Clients {
			if c.Session == l.Session {
				check = true
				break
			}
		}

		if check == false {
			response.Write([]byte(`{state":"failed"}`))
			db.Invalid(&db.InvalidInfo{
				Addr: request.RemoteAddr,
				Time: time.Now(),
				Type: db.InvalidHttps,
			})
			return
		}

		info := map[string]interface{}{
			"membership": l.Membership,
			"state":      l.State,
		}
		data, _ := json.Marshal(info)

		result := make(chan *MessagePkg, 1)
		defer close(result)

		pkg := &MessagePkg{
			Type: PkgTypeChannel,
			Ctx: &Context{
				HomeId:   l.Home,
				MemberId: l.Membership,
				Result:   result,
			},
			Msg: &Message{
				Path:   "home/location",
				Method: "post",
				Home:   l.Home,
				Data:   data,
			},
		}

		if workers.recPkg != nil {
			workers.recPkg <- pkg
		}

		select {
		case ack, ok := <-result:
			if ok {
				log.Debug("post ack: %s", ack)
				ackData, _ := json.Marshal(ack.Msg)
				response.Write([]byte(ackData))
			}

		case <-time.After(time.Second * 3):
			response.Write([]byte(`{state":"timeout"}`))
			return
		}

	}

}

func init() {
	router["location"] = &location{}
}
